<template>
  <div class="forms">
    <Header title="我的报表"/>
    <main class="forms-main">
      <div class="forms-date">
        <van-icon @click="arrowLeftClick" v-if="isArrowLeftShow" name="arrow-left" size="4vw"/>
        {{ currentFormatMonth }}
        <van-icon @click="arrowRightClick" v-if="isArrowRightShow" name="arrow" size="4vw"/>
      </div>
      <div class="forms-canvas-box">
        <canvas id="forms-canvas" class="forms-canvas"></canvas>
        <div class="forms-summary-box">
          <div class="forms-summary-title">
            {{ getSummaryTitle }}
          </div>
          <div class="forms-summary-amount">
            {{ formatNumber(getMonthSummaryAmount) }}
          </div>
          <div @click="toggleType" class="forms-summary-toggle">
            <van-icon name="exchange" size="5vw"/>
          </div>
        </div>
      </div>
      <div class="forms-tag-summary-box">
        <div v-for="formsSummary in getFormsSummary" :key="formsSummary.tagId" class="forms-tag-summary">
          <div class="current-tag">
            <div 
              :style="`background-color:${getCurrentTag(formsSummary.tagId).color}`" 
              class="tag-icon">
              <van-icon :name="getCurrentTag(formsSummary.tagId).icon" size="5vw"/>
            </div>
            <span class="current-tag-name">
              {{ getCurrentTag(formsSummary.tagId).name }}
            </span>
          </div>
          <div class="current-value" :title="formsSummary.summaryAmount">
            {{ formatNumber(formsSummary.summaryAmount) }}
          </div>
          <div class="current-proportion">
            {{ formatProportion(getProportion(formsSummary.summaryAmount)) }}%
          </div>
        </div>
      </div>
      <div v-if="getFormsSummary.length === 0" class="forms-tips">
        当前没有数据哦
      </div>
    </main>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import { BillModule, BillType, IBillSummary } from '../../store/modules/bill';
import { IBillTag, UserModule } from '../../store/modules/user';
import { formatNumber } from '../../utils/formatNumber';
import { getMonth } from '../../utils/date';
import Header from '../../components/Header/index.vue';

interface IFormsSummary {
  tagId: number;
  summaryAmount: number;
}

interface ICanvasOptions {
  angles: number[];
  colors: string[];
}

@Component({
  name: 'Forms',
  components: {
    Header,
  },
})
export default class extends Vue {
  private currentSummaryType: BillType = BillType.Expense;
  private currentFormatMonth: string = getMonth(new Date());

  private mounted() {
    this.drawCircle(this.getCanvasOptions(this.getFormsSummary));
  }

  private get isExpense(): boolean {
    return this.currentSummaryType === BillType.Expense;
  }
  // 判断日期左边箭头是否显示
  private get isArrowLeftShow() {
    return this.getSummaryMonth.length !== 0 && this.getSummaryMonth.indexOf(this.currentFormatMonth) !== 0;
  }
  // 判断日期右边箭头是否显示
  private get isArrowRightShow() {
    return this.getSummaryMonth.length !== 0 && this.getSummaryMonth.indexOf(this.currentFormatMonth) !== this.getSummaryMonth.length - 1;
  }
  // 获取所有数据汇总月份信息，并做排序处理，返回数据：['202006', '202007']
  private get getSummaryMonth() {
    return BillModule.billSummary.reduce((pre: string[], cur: IBillSummary): string[] => {
      pre.push(cur.month);
      return pre;
    }, []).sort();
  }
  // 获取当前报表汇总数据title
  private get getSummaryTitle(): string {
    return this.isExpense ? '总支出' : '总收入';
  }
  // 获取当前月份汇总数据总金额
  private get getMonthSummaryAmount(): number {
    let summaryAmount = 0;
    const currentBillSummary = BillModule.billSummary.find((item) => {
      return item.month === this.currentFormatMonth;
    });
    if (currentBillSummary) {
      summaryAmount = this.isExpense ? currentBillSummary.expenseSummary : currentBillSummary.revenueSummary;
    }
    return summaryAmount;
  }
  // 获取报备详细汇总数据，并进行排序
  private get getFormsSummary(): IFormsSummary[] {
    const formsSummary: IFormsSummary[] = [];
    BillModule.bills.forEach((bill) => {
      if (this.currentFormatMonth === getMonth(new Date(bill.createTime)) && this.currentSummaryType === bill.billType)  {
        const formsSummaryIndex = formsSummary.findIndex((item) => {
          return item.tagId === bill.billTagId;
        });
        if (formsSummaryIndex !== -1) {
          formsSummary[formsSummaryIndex].summaryAmount += bill.amount;
        } else {
          formsSummary.push({
            tagId: bill.billTagId,
            summaryAmount: bill.amount,
          });
        }
      }
    });
    formsSummary.sort((a: IFormsSummary, b: IFormsSummary): number => {
      return b.summaryAmount - a.summaryAmount;
    });
    return formsSummary;
  }
  // 获取当前标签信息
  private get getCurrentTag() {
    return (tagId: number): IBillTag => {
      return UserModule.userConfig.billTagList.find((item) => {
        return item.tagId === tagId;
      }) as IBillTag;
    };
  }
  // 格式化数据，自动补0
  private get formatNumber() {
    return (amount: number): string => {
      return formatNumber(amount);
    };
  }
  // 计算当前金额占汇总数据的百分百
  private get getProportion() {
    return (amount: number): number => {
      return amount / this.getMonthSummaryAmount;
    };
  }
  // 格式化百分百数据，自动补0
  private get formatProportion() {
    return (proportion: number) => {
      return formatNumber(proportion * 100);
    };
  }
  // 获取画布所需配置信息，从报备详细汇总数据里提取
  private get getCanvasOptions() {
    return (formsSummary: IFormsSummary[]): ICanvasOptions => {
      const options: ICanvasOptions = {
        angles: [],
        colors: [],
      };
      formsSummary.forEach((item) => {
        options.angles.push(this.getProportion(item.summaryAmount));
        options.colors.push(this.getCurrentTag(item.tagId).color);
      });
      return options;
    };
  }

  // 日期左边箭头点击事件，切换当前日期
  private arrowLeftClick() {
    const currentIndex = this.getSummaryMonth.indexOf(this.currentFormatMonth);
    this.currentFormatMonth = this.getSummaryMonth[currentIndex - 1];
  }
  // 日期右边箭头点击事件，切换当前日期
  private arrowRightClick() {
    const currentIndex = this.getSummaryMonth.indexOf(this.currentFormatMonth);
    this.currentFormatMonth = this.getSummaryMonth[currentIndex + 1];
  }
  // 切换报备类型，支出/收入
  private toggleType() {
    this.currentSummaryType = this.isExpense ? BillType.Revenue : BillType.Expense;
    this.drawCircle(this.getCanvasOptions(this.getFormsSummary));
  }
  // 使用canvas画图表
  private drawCircle(options: ICanvasOptions) {
    options.angles = options.angles;
    options.colors = options.colors;
    const oBoxOne: any = document.getElementById('forms-canvas');
    if (!oBoxOne) {
      return;
    }
    const sCenter: number = oBoxOne.clientHeight / 2;
    const ctx = oBoxOne.getContext('2d');
    ctx.canvas.width = ctx.canvas.offsetWidth;
    ctx.canvas.height = ctx.canvas.offsetHeight;
    let nBegin: number = -Math.PI / 2;
    const nEnd: number = Math.PI * 2;
    function draw(cur: number, color: string, curIndex: number) {
      ctx.beginPath();
      ctx.moveTo(sCenter, sCenter);
      ctx.arc(sCenter, sCenter, sCenter, nBegin, (nEnd * cur) + nBegin, false);
      nBegin = (nEnd * cur) + nBegin;
      ctx.closePath();
      ctx.fillStyle = color;
      ctx.fill();
    }
    options.angles.reduce((pre, cur, curIndex) => {
      if (curIndex === options.angles.length - 1) {
        cur = 1 - pre;
      }
      draw(cur, options.colors[curIndex], curIndex);
      return pre + cur;
    }, 0);
  }
}
</script>

<style scoped>
.forms {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  height: 100%;
  width: 100%;
}
.forms-main {
  height: 100%;
  width: 100%;
  border-top: 1px solid #D0CECF;
  border-bottom: 1px solid #D0CECF;
  overflow: auto;
}
.forms-date {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 80px;
  background-color: #F7F7F7;
}
.forms-canvas-box {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 750px;
  height: 500px;
  background-color: white;
  border-bottom: 1px solid #D0CECF;
}
.forms-canvas {
  width: 400px;
  height: 400px;
  border-radius: 50%;
  background-color: #F7F7F7;
}
.forms-summary-box {
  position: absolute;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  width: 250px;
  height: 250px;
  top: 125px;
  left: 250px;
  border-radius: 50%;
  background-color: white;
}
.forms-summary-title {
  font-size: 20px;
  color: gray;
  padding: 5px;
}
.forms-summary-amount {
  font-size: 40px;
  padding: 5px;
}
.forms-summary-toggle {
  width: 40px;
  color: #409EFF;
}
.forms-tag-summary {
  position: relative;
  display: flex;
  align-items: center;
  height: 100px;
  border-bottom: 1px solid #D0CECF;
}
.current-tag {
  display: flex;
  align-items: center;
  height: 100px;
  width: 300px;
  padding-left: 30px;
}
.current-tag-name {
  float: right;
  flex: 1;
  height: 100px;
  line-height: 100px;
  padding-left: 20px;
  overflow: hidden;
}
.current-value {
  flex: 1;
  width: 100%;
  height: 100px;
  line-height: 100px;
  text-align: right;
  padding-right: 20px;
  overflow: hidden;
  text-overflow:ellipsis;
}
.tag-icon {
  width: 60px;
  height: 60px;
  border-radius: 50%;
  color: white;
  text-align: center;
}
.tag-icon .van-icon{
  line-height: 60px;
}
.current-proportion {
  position: absolute;
  line-height: 100px;
  left: 330px;
}
.forms-tips {
  text-align: center;
  font-size: 50px;
  color: #409EFF;
  padding:20px;
}
</style>
